package com.zx.mes.hyl.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zx.mes.hyl.pagemodel.PageParam;
import com.zx.mes.hyl.response.ObjectRestResponse;
import com.zx.mes.hyl.response.TableResultResponse;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 重构基础 controller 类
 *
 * @author 华云龙
 * @date 2018-6-14
 */
@Log4j2
public class BaseController<Biz extends IService<Entity>, Entity> {

    @SuppressWarnings({"SpringJavaAutowiredMembersInspection"})
    @Autowired
    protected Biz biz;

    @SuppressWarnings("SpringJavaAutowiredMembersInspection")
    @Autowired
    protected BaseControllerExt baseControllerExt;

    /**
     * 使用要求:所有的表都必需有唯一key值,且名称为 REFLECTION_FIELD_NAME (id)
     *
     * @param entity 实体类(pojo)
     * @return ObjectRestResponse
     */
    @ApiOperation(value = "添加一笔数据", notes = "根据id自生成(数据库),还是前端生成(自身成36位)")
    @PostMapping(value = "/add")
    public ObjectRestResponse<Entity> add(@RequestBody Entity entity) {
        ObjectRestResponse.Builder<Entity> builder = new ObjectRestResponse.Builder<>();

        biz.save(entity);
        builder.message("数据插入成功!")
                .rel(true);

        return builder.build();
    }

    @ApiOperation(value = "根据所传id(数据库表的主键必需是id才能用)")
    @GetMapping(value = "getOne/{id}")
    public ObjectRestResponse get(@ApiParam("id 是数据库的唯一主键") @PathVariable String id) {
        return new ObjectRestResponse.Builder<Entity>()
                .data(biz.getById(id))
                .message("单笔数据获取成功!")
                .build();
    }

    /**
     * {
     * "status": 200,
     * "message": "数据更新成功!",
     * "data": null,
     * "rel": true
     * }
     *
     * @param entity 对应实体类
     * @return ObjectRestResponse
     */
    @ApiOperation(value = "单笔更新操作", notes = "必需根据id来更新")
    @PutMapping(value = "update")
    public ObjectRestResponse<Entity> update(@RequestBody Entity entity) {
        ObjectRestResponse.Builder<Entity> builder = new ObjectRestResponse.Builder<>();

        biz.updateById(entity);
        builder.message("数据更新成功!")
                .rel(true);

        return builder.build();
    }

    @ApiOperation(value = "单笔删除操作", notes = "必需根据id来删除")
    @DeleteMapping(value = "delete/{id}")
    public ObjectRestResponse<Entity> remove(@PathVariable String id) {
        ObjectRestResponse.Builder<Entity> builder = new ObjectRestResponse.Builder<>();

        biz.remove(new QueryWrapper<Entity>().eq(true, "id", id));
        builder.message("数据删除成功!")
                .rel(true);

        return builder.build();
    }

    @ApiOperation(value = "获取所有的数据", notes = "一般不推荐使用,小数据量可以")
    @GetMapping(value = "/all")
    public List<Entity> all() {
        return biz.list(null);
    }

    @ApiOperation(value = "分页操作", notes = "params HashMap example = \"page=1&limit=5\"")
    @SuppressWarnings({"unchecked"})
    @GetMapping(value = "/page")
    public TableResultResponse list(@RequestParam Map<String, Object> params, Entity entity) {

        log.debug("分页值:" + params.toString() + "  实体值:" + entity.toString());
        TableResultResponse.Builder<Entity> builder = new TableResultResponse.Builder<>();

        /// 获取分页信息
        PageParam extPageParams = baseControllerExt.getPageParams(params);

        List<Entity> list = biz.page(new Page<>(extPageParams.getPage(), extPageParams.getLimit()), null).getRecords();

        /// 解决问题:当无数据返回时
        if (null == list || list.size() == 0) {
            builder.message("无数据")
                    .page(0)
                    .rows(null);
        } else {
            builder.message("分页查询结果")
                    .total(list.size())
                    .total(biz.count(null))
                    .page(extPageParams.getPage())
                    .rows(list);
        }
        return builder.build();
    }
}
